﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


using System;
using System.Globalization;

namespace Tesla.Graphics {
    /// <summary>
    /// Key representing a RenderState - it's type and its hash value.
    /// </summary>
    public struct RenderStateKey : IEquatable<RenderStateKey> {
        private int _key;
        private RenderStateType _type;

        /// <summary>
        /// Get the render state key, usually a hash code.
        /// </summary>
        public int Key {
            get {
                return _key;
            }
        }

        /// <summary>
        /// Get the state type.
        /// </summary>
        public RenderStateType StateType {
            get {
                return _type;
            }
        }

        /// <summary>
        /// Creates a new RenderStateKey, initializing all fields.
        /// </summary>
        /// <param name="key">State key, usually hash code</param>
        /// <param name="stateType">State type, for identification</param>
        public RenderStateKey(int key, RenderStateType stateType) {
            _key = key;
            _type = stateType;
        }

        /// <summary>
        /// Tests RenderStateKeys for equality, their keys and render
        /// state types.
        /// </summary>
        /// <param name="value1">First key</param>
        /// <param name="value2">Second key</param>
        /// <returns>True if state types and keys match</returns>
        public static bool operator==(RenderStateKey value1, RenderStateKey value2) {
            if((int) value1.StateType == (int) value2.StateType
                && value1.Key == value2.Key) {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Tests RenderStateKeys for inequality, their keys and
        /// render state types.
        /// </summary>
        /// <param name="value1">First key</param>
        /// <param name="value2">Second key</param>
        /// <returns>True if state types or keys do not match</returns>
        public static bool operator!=(RenderStateKey value1, RenderStateKey value2) {
            if(value1.Key != value2.Key
                || (int) value1.StateType != (int) value2.StateType) {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Hash code for the RenderStateKey, is the key itself.
        /// </summary>
        /// <returns>Key</returns>
        public override int GetHashCode() {
            return Key;
        }

        /// <summary>
        /// Checks for equality with the object.
        /// </summary>
        /// <param name="obj">Object to test</param>
        /// <returns>True if keys and types match</returns>
        public override bool Equals(object obj) {
            if(obj != null && obj is RenderStateKey) {
                RenderStateKey other = (RenderStateKey) obj;
                if((int) other.StateType == (int) this.StateType
                && other.Key == this.Key) {
                    return true;
                }
                return false;
            }
            return false;
        }

        /// <summary>
        /// Checks for equality with the other state key.
        /// </summary>
        /// <param name="other">Other render state key</param>
        /// <returns>True if keys and types match</returns>
        public bool Equals(RenderStateKey other) {
            if((int) other.StateType == (int) this.StateType
                && other.Key == this.Key) {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Creates a string representation of the RenderStateKey
        /// </summary>
        /// <returns>String representing key and type</returns>
        public override string ToString() {
            CultureInfo info = CultureInfo.CurrentCulture;
            return String.Format(info, "{RenderStateKey [StateType : {0}, Key: {1}]}",
                new Object[] { StateType.ToString(), Key.ToString()});
        }
    }
}
